/**
 *  This file is part of MunchLevel.
 *
 *  MunchLevel is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MunchLevel is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MunchLevel.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.munchlevel.util;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;

import com.gandulf.guilib.download.AbstractDownloader;
import com.gandulf.guilib.download.Downloader;
import com.gandulf.guilib.download.DownloaderWrapper;
import com.gandulf.guilib.util.Debug;
import com.munchlevel.MunchLevelApplication;
import com.munchlevel.MyPreferenceActivity;
import com.munchlevel.R;

public class ThemeManager {

	public static final File THEMES_DIR = new File(MunchLevelApplication.SD_DIR, "themes");

	public static final String DEFAULT_THEME = "default";

	private static Map<ThemeItem, WeakReference<Drawable>> imageCache = new HashMap<ThemeManager.ThemeItem, WeakReference<Drawable>>(
			ThemeItem.values().length);
	private static String cacheTheme = null;

	private Context context;

	private static List<String> themes = null;

	private Themeable themeable;

	private BroadcastReceiver broadcastReceiver;

	public ThemeManager(Context context) {
		this.context = context;

		broadcastReceiver = new BroadcastReceiver() {

			@Override
			public void onReceive(Context context, Intent intent) {

				int result = intent.getIntExtra(Downloader.INTENT_RESULT, -1);

				intent.getSerializableExtra(Downloader.INTENT_EXCEPTION);
				intent.getStringExtra(Downloader.INTENT_ERROR);

				if (themeable != null) {
					switch (result) {
					case Downloader.RESULT_OK:
						themeable.applyTheme();
						break;
					case Downloader.RESULT_CANCELED:
						themeable.resetTheme();
						break;
					case Downloader.RESULT_ERROR:
						themeable.resetTheme();
					}
				}

			}
		};
		context.registerReceiver(broadcastReceiver, new IntentFilter(Downloader.ACTION_UNZIP_COMPLETE));
	}

	public enum ThemeItem {
		BgMale(R.drawable.default_m, "_m.jpg"), BgFemale(R.drawable.default_f, "_f.jpg"), BgMaleLandscape(
				R.drawable.default_m_land, "_m_land.jpg"), BgFemaleLandscape(R.drawable.default_f_land, "_f_land.jpg"), BgMonster(
				R.drawable.default_monster, "_monster.jpg"), BgSplash(R.drawable.default_splash, "_splash.jpg"), BgSplashLandscape(
				R.drawable.default_splash_land, "_splash_land.jpg"), BgFightLandscape(R.drawable.default_fight,
				"_fight_land.jpg");

		private int defaultId;

		private String postfix;

		private ThemeItem(int defaultId, String postfix) {
			this.defaultId = defaultId;
			this.postfix = postfix;
		}

		public String getPostfix() {
			return postfix;
		}

		public int getDefaultResoureId() {
			return defaultId;
		}
	}

	public void close() {
		context.unregisterReceiver(broadcastReceiver);
	}

	public void refreshThemes() {
		themes = null;
	}

	public List<String> getThemes() {
		if (themes == null) {

			themes = new LinkedList<String>();
			themes.add(ThemeManager.DEFAULT_THEME);

			if (THEMES_DIR.isDirectory()) {
				HashMap<String, Set<ThemeItem>> themeItems = new HashMap<String, Set<ThemeItem>>();

				for (File file : THEMES_DIR.listFiles()) {
					if (file.isFile()) {
						String name = file.getName();

						for (ThemeItem item : ThemeItem.values()) {
							if (name.endsWith(item.getPostfix())) {
								String themeName = name.substring(0, name.length() - item.getPostfix().length());

								Set<ThemeItem> themeItemList = themeItems.get(themeName);
								if (themeItemList == null) {
									themeItemList = new HashSet<ThemeManager.ThemeItem>();
									themeItems.put(themeName, themeItemList);
								}
								themeItemList.add(item);
								break;
							}
						}
					}
				}

				for (String themeName : themeItems.keySet()) {

					Set<ThemeItem> themeItemList = themeItems.get(themeName);

					if (themeItemList != null && themeItemList.containsAll(Arrays.asList(ThemeItem.values()))) {
						themes.add(themeName);
					}

				}
			}
		}
		return themes;
	}

	public static Drawable getThemeDrawable(ThemeItem themeItem) {

		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(MunchLevelApplication.getInstance()
				.getBaseContext());

		String name = pref.getString(MyPreferenceActivity.KEY_THEME, DEFAULT_THEME);
		Drawable bg = null;

		if (cacheTheme == null || !name.equals(cacheTheme)) {
			Debug.verbose("clearing image cache");
			imageCache.clear();
			cacheTheme = name;
		}

		if (DEFAULT_THEME.equals(name)) {
			bg = MunchLevelApplication.getInstance().getResources().getDrawable(themeItem.getDefaultResoureId());
			imageCache.put(themeItem, new WeakReference<Drawable>(bg));
		}

		String path = THEMES_DIR.getAbsolutePath() + "/" + name + themeItem.getPostfix();

		if (bg == null && imageCache.containsKey(themeItem)) {
			Debug.verbose("loading theme bg from cache " + path);
			bg = imageCache.get(themeItem).get();
		}

		if (bg == null) {
			Debug.verbose("loading theme bg from disk " + path);
			bg = Drawable.createFromPath(path);
			imageCache.put(themeItem, new WeakReference<Drawable>(bg));
		}

		return bg;
	}

	public void applyTheme(final Themeable themeable) {

		this.themeable = themeable;

		if (!themeable.applyTheme()) {

			AlertDialog.Builder builder = new AlertDialog.Builder(context);

			builder.setTitle(R.string.title_theme_not_found);
			builder.setMessage(R.string.msg_download_theme);
			builder.setPositiveButton(R.string.btn_download, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					AbstractDownloader downloader = DownloaderWrapper.getInstance(
							MunchLevelApplication.SD_DIR.getAbsolutePath(), context);

					downloader.addPath(MyPreferenceActivity.PATH_THEMES);
					downloader.downloadZip();
				}
			});

			builder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					themeable.resetTheme();
					dialog.dismiss();
				}
			});

			builder.show();
		}
	}
}
